We are working with a dataset from a czech bank.

Below we have loaded all the packages and data as well as organized and sturctured it so we can work with it. loading all packages and data

library(tidyverse)
library(tidymodels)
library(ggmosaic)
library(ggalluvial)
library(rpart)
library(rpart.plot)
library(gridExtra)
library(usethis)
library(ggplot2)
library(dplyr)

account <- read.csv('./account.csv', sep = ";")
card <- read.csv('./card.csv', sep = ";")
client <- read.csv('./client.csv', sep = ";")
disp <- read.csv('./disp.csv', sep = ";")
district <- read.csv('./district.csv', sep = ';')
loan <- read.csv('./loan.csv', sep = ";")
order <- read.csv('./order.csv', sep = ";")
trans <- read.csv('./trans.csv', sep = ";")

clean/organize account


#reformat date
account$date_ymd <- format(as.Date(as.character(account$date), "%y%m%d"), "19%y/%m/%d") 

account <- account %>%
  select(-date)

#factorize variables
account <- account %>% 
  mutate (frequency = as_factor(frequency), 
          date_ymd = as.Date(date_ymd)
          ) %>%
  mutate(frequency = case_when(
    frequency == 'POPLATEK MESICNE' ~ 'monthly issuance',
    frequency == 'POPLATEK TYDNE' ~ 'weekly issuance',
    frequency == 'POPLATEK PO OBRATU' ~ 'issuance after transaction'
  ))

clean/organize card


#reformat date
card$issued_date <- format(as.Date(as.character(card$issued), "%y%m%d"), "19%y/%m/%d")

#factorize variables
card <- card %>%
  mutate(type = as_factor(type), 
         issued_date = as.Date(issued_date)
         )
  

clean/organize client (Dani fragen)


#reformat birth_number

client <- client %>%
  mutate(month = substr(birth_number, 3, 4)) %>%
  mutate(month = strtoi(month))

client <- client %>%
  mutate(gender = case_when(
    month > 12 ~ 'f',
    TRUE ~ 'm')
  )

client <- client %>%
  mutate(birth_number = as.numeric(birth_number))

client <- client %>%
  mutate(birth_number = case_when(
    month > 12 ~ birth_number - 5000,
    TRUE ~ birth_number)
  )



client$birthday <- format(as.Date(as.character(client$birth_number), "%y%m%d"), "19%y/%m/%d")

#factorize variables
client <- client %>%
  mutate(district_id = as_factor(district_id), 
         gender = as_factor(gender),
         birthday = as.Date(birthday)
         )
project_date = '1998/1/1'

library(eeptools)
x <- as.Date(c("1998-01-01"))


client$age <- floor(age_calc(as.Date(client$birthday),x, units = "years"))

library(eeptools)
x <- as.Date(c("1998-01-01"))


client$age <- floor(age_calc(as.Date(client$birthday),x, units = "years"))

birthday proper shape

client <- client %>%
  mutate(
    birth_number = birth_number + 19000000
  )

clean/organize disp


#factorize variables
disp <- disp %>%
  mutate(type = as_factor(type)
         )

clean/organize district


#rename coluns
names(district) <- c('district_id', 'district_name', 'region', 'habitants', 'municipalities<499',
                     'municipalities<500-1000', 'municipalities<2000-9999', 'municipalities>10000', 'cities',
                     'ratio_urban_inhabitants', 'average_salary', 'unemployment_rate_1995', 'unemployment_rate_1996',
                     'enterpreneurs_per_1000', 'crimes_1995', 'crimes_1996')

#factorize variables
district <- district %>%
  mutate(district_name = as_factor(district_name), region = as_factor(region))

#change datatype to numeric/int
district <- district %>% 
  mutate(unemployment_rate_1995 = as.numeric(unemployment_rate_1995), 
         enterpreneurs_per_1000 = strtoi(enterpreneurs_per_1000), 
         crimes_1995 = strtoi(crimes_1995)
         )
Warning: Problem with `mutate()` column `unemployment_rate_1995`.
ℹ `unemployment_rate_1995 = as.numeric(unemployment_rate_1995)`.
ℹ NAs introduced by coercion
#str(district)

clean/organize loan


#reformat date
loan$date_issued <- format(as.Date(as.character(loan$date), "%y%m%d"), "19%y/%m/%d")
loan <- loan %>%
  select(-date)


#factorize variables
loan <- loan %>%
  mutate(duration = as_factor(duration), 
         status = as_factor(status),
         date_issued = as.Date(date_issued)
         )

clean/organize order


#factorize variables
order <- order %>%
  mutate(bank_to = as_factor(bank_to), 
         k_symbol = as_factor(k_symbol)
         )


order <- order %>%
  mutate(k_symbol = case_when(
    k_symbol == 'POJISTNE' ~ 'issurance payment',
    k_symbol == 'SIPO' ~ 'household',
    k_symbol == 'LEASING' ~ 'leasing',
    k_symbol == 'UVER' ~ 'loan payment'
  )
    
  )
#str(order)

clean/organize trans


#reformat date
trans$date_dmy <- format(as.Date(as.character(trans$date), "%y%m%d"), "19%y/%m/%d")

trans <- trans %>%
  select(-date)

#factorize variables
trans <- trans %>%
  mutate(type = as_factor(type),
         operation = as_factor(operation),
         k_symbol = as_factor(k_symbol),
         date_dmy = as.Date(date_dmy)
         )

trans <- trans %>%
  mutate(type = case_when(
    type == 'PRIJEM' ~ 'credit',
    type == 'VYDAJ' ~ 'withdrawal',
    type == 'VYBER' ~ 'withdrawal in cash'
  )) %>%
  mutate(operation = case_when(
    operation == 'VYBER KARTOU' ~ 'credit card withdrawal',
    operation == 'VKLAD' ~ 'credit in cash',
    operation == 'PREVOD Z UCTU' ~ 'collection from other bank',
    operation == 'VYBER' ~ 'withdrawal in cash',
    operation == 'PREVOD NA UCET' ~ 'remittance to other bank'
  )) %>%
  mutate(k_symbol = case_when(
    k_symbol == 'POJISTNE' ~ 'insurrance payment',
    k_symbol == 'SLUZBY' ~ 'payment for statement',
    k_symbol == 'UROK' ~ 'interest credited',
    k_symbol == 'SIPO' ~ 'hosehold',
    k_symbol == 'DUCHOD' ~ 'old-age pension',
    k_symbol == 'UVER' ~ 'loan payment'
  ))

Bring together client and disp

client_disp <- full_join(
    disp,client, by = 'client_id'
) 

client_disp <- full_join(
  client_disp, card, by = 'disp_id'
)

client_disp <- client_disp %>%
  rename(
    type_client = type.x,
    type_card = type.y,
    card_issued = issued_date
  ) %>%
  select(
    - birth_number,
    - month,
    - issued
  )


#gender count aller clients
gender_group <- client_disp %>%
 count(gender)
gender_group

#type count aller clients
gen_client_group <- client_disp %>%
  count(type_client)
gen_client_group

#gender count nach type
gen_client_test<- client_disp %>%
  group_by(gender) %>%
  count(type_client)
gen_client_test

#herausfinden ob 1 client mehrere accounts

# gender spread czeck republik 1998 female 51.37% https://data.worldbank.org/indicator/SP.POP.TOTL.FE.ZS?end=1998&locations=CZ&start=1998

Fragestellung Recherche Jenni

Quick overview research to get to know the outlines of the dataset and decide where to go deeper.

First i wanted to see the genderdistribution of the clients.

As we can see in the Plot below, there are slightly less women than man, but over all the gender is pretty balanced out.

client_gender_j <-ggplot(
  client, aes(x = gender, fill = gender))+
  geom_bar()+
  ggtitle('\nClients spread on gender\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )+
  labs( y= '\nNumber of Clients\n', x = '\nGender\n')
client_gender_j

client_owner_j <-ggplot(
  client_disp, aes(x = type_client,fill = gender ))+
  geom_bar(position ='dodge')+
  ggtitle('\nOwner/Disponent spread on gender\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )+
  geom_text(aes(label = ..count..), stat = "count", position =  position_dodge(width = 0.9), vjust = 2)+
  labs( y= '\nNumber of Clients\n', x = '\nGender\n')
client_owner_j


#weiter untersuchen, wer macht die Überweisungen und altersgruppen
#check mit count

print(count(client_disp))

owner_total <- sum(client_disp$type_client== 'OWNER')
cat('Total OWNER:', owner_total) 
Total OWNER: 4500
dispo_total <- sum(client_disp$ype_client== 'DISPONENT')
cat('Total DISPONENT: ', dispo_total)
Total DISPONENT:  0
female_client <- sum(client_disp$gender == 'f')
cat('Total female clients: ',female_client)
Total female clients:  2645
male_client <- sum(client_disp$gender == 'm')
cat('Total male clients: ',female_client)
Total male clients:  2645
print('There is an equal amount of male and female clients. That is very surprising. We will have a deeper look at this.')
[1] "There is an equal amount of male and female clients. That is very surprising. We will have a deeper look at this."
# da stimmt etwas nicht. Bei clients sagts es sind 5369 observationen, wenn mann nach gender odrnet sind immer zu viele das erste geschlecht.????

      

The general information of the Age of the clients is a good base information as well.

We gan see in the plot below most clients are between 20 and 55 years old.

client_age_j <- ggplot(
  client, aes(x = age, colour = gender))+
  #geom_bar(alpha = 0.5)+
  geom_density()+
  ggtitle('\nClientspread on age, separated by gender\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )+
  labs( y = '\ndensity\n', x = '\nAge\n')
  
client_age_j


age_count <- client %>%
  group_by(gender, age) %>%
  summarise(
    count = n()
  )
`summarise()` has grouped output by 'gender'. You can override using the `.groups` argument.
age_count


client_age_jl <- ggplot(
  age_count, aes(x = age, colour = gender, y = count))+
  #geom_bar(alpha = 0.5)+
  # geom_point()+
  geom_line()+
  ggtitle('\nClientspread on age, separated by gender\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )
client_age_jl

NA
NA
card_type_j <- ggplot(
  card, aes(x = type, fill = type))+
  geom_bar()+
  ggtitle('\nSpread of card types\n')+
  geom_text(aes(label = ..count..), stat = "count", position =  position_dodge(width = 0.9), vjust = 2)+
  theme(
    plot.title = element_text(hjust = 0.5)
    )
  
card_type_j


card_type_jx <- ggplot(
  client_disp, aes(x = type_client, fill = gender))+
  geom_bar(position = 'dodge')+
  ggtitle('\nSpread of card types\n')+
  geom_text(aes(label = ..count..), stat = "count", position =  position_dodge(width = 0.9), vjust = 2)+
  theme(
    plot.title = element_text(hjust = 0.5)
    )
  
card_type_jx

card_type_g_j <- ggplot(
  client_disp, aes(x = type_card, fill = gender))+
  geom_bar(position = 'dodge')+
  ggtitle('\nSpread of card types\n')+
  geom_text(aes(label = ..count..), stat = "count", position =  position_dodge(width = 0.9), vjust = 2)+
  theme(
    plot.title = element_text(hjust = 0.5)
    )
  
card_type_g_j

card_type_age_g <- ggplot(
  client_disp, aes(x = age, colour = type_card))+
  geom_density(position = 'dodge')+
  ggtitle('\nSpread of card types\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )
card_type_age_g
Warning: Width not defined. Set with `position_dodge(width = ?)`

age_card <- client_disp %>%
  group_by( type_card, age ) %>%
  summarise(
    count = n()
  )
`summarise()` has grouped output by 'type_card'. You can override using the `.groups` argument.
age_card

card_type_age <- ggplot(
  age_card, aes(x = age, y = count, colour = type_card))+
  geom_line(position = 'dodge')+
  ggtitle('\nSpread of card types\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )
  
card_type_age
Warning: Width not defined. Set with `position_dodge(width = ?)`

age_card_m <- filter(client_disp, gender == 'm')
age_card_m

age_card_f <- filter(client_disp, gender == 'f')
age_card_f

age_card_m <- age_card_m %>%
  group_by(age, type_card) %>%
  summarise(
    count = n()
  ) 
`summarise()` has grouped output by 'age'. You can override using the `.groups` argument.
age_card_f <- age_card_f %>%
  group_by(age, type_card) %>%
  summarise(
    count = n()
  ) 
`summarise()` has grouped output by 'age'. You can override using the `.groups` argument.
card_type_age_m <- ggplot(
  age_card_m, aes(x = age, y = count, colour = type_card))+
  geom_line(position = 'dodge')+
  ggtitle('\nSpread of card types of male clients\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )
  
card_type_age_m
Warning: Width not defined. Set with `position_dodge(width = ?)`

card_type_age_f <- ggplot(
  age_card_f, aes(x = age, y = count, colour = type_card))+
  geom_line(position = 'dodge')+
  ggtitle('\nSpread of card types of female clients\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )
  
card_type_age_f
Warning: Width not defined. Set with `position_dodge(width = ?)`

<<<<<<< HEAD

# filter by card, make dataframe for each card type

#wenn junior_card is true pipe into new data frame
client_junior <- filter(client_disp , type_card == 'junior')
client_classic <- filter(client_disp , type_card == 'classic')
client_gold <- filter(client_disp , type_card == 'gold')

client_all_cards <- client_disp %>%
  filter(!is.na(type_card))

client_na <- client_disp %>%
  filter(is.na(type_card))

client_na

client_na_junior <- filter(client_na, age <= 23)
client_na_classic_gold <- filter(client_na, age > 23)
# client_junior$age_card_issued2 <- client_junior$card_issued - client_junior$birthday 
client_junior$age_card_issued <- floor(age_calc(as.Date(client_junior$birthday),client_junior$card_issued, units = "years"))

junior_issued_age_viz <- ggplot( client_junior, aes( x = age_card_issued, fill = gender))+
  geom_bar( position = 'dodge'
  )+
  # geom_density()+
  ggtitle('\nJunior cards issued on age of owner\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )
junior_issued_age_viz


client_na_junior_age_viz <- ggplot(client_na_junior, aes(x=age, fill=gender))+
  geom_bar(position = 'dodge')+
  ggtitle('\npotential junior card clients age spread\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
  )
client_na_junior_age_viz

client_classic$age_card_issued <- floor(age_calc(as.Date(client_classic$birthday),client_classic$card_issued, units = 'years'))
client_gold$age_card_issued <- floor(age_calc(as.Date(client_gold$birthday),client_gold$card_issued, units = 'years'))

classic_issued_age_viz <- ggplot(client_classic, aes( x = age, fill = gender))+
  geom_bar(position = 'dodge')+
  ggtitle('\nClassic cards issued on age of owner\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )
classic_issued_age_viz


#nehmen wir alle ab 20 zu der gruppe potential classic????????

gold_issued_age_viz <- ggplot(client_gold, aes( x = age, fill = gender))+
  geom_bar(position = 'dodge')+
  ggtitle('\nGold cards issued on age of owner\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )
gold_issued_age_viz

#join card information to traansactions via account id

cardowner_transactions <- inner_join(client_all_cards, trans, by = 'account_id') %>%
  mutate(trans_credit =
    case_when(
      type == 'credit' ~ 1,
      type != 'credit' ~ 0
    )
  ) %>%
  mutate(trans_withdrawal =
           case_when(
             type == 'withdrawal' ~ 1,
             type != 'withdrawal' ~ 0
           )
  ) %>%
  mutate(
    type = as.factor(type),
    operation = as.factor(operation),
    k_symbol = as.factor(k_symbol),
    bank = as.factor(bank)
  )

junior_card_transactions <- filter(cardowner_transactions, type_card == 'junior')
classic_card_transactions <- filter(cardowner_transactions, type_card == 'classic')
gold_card_transactions <- filter(cardowner_transactions, type_card == 'gold')
junior_card_transactions_2 <- junior_card_transactions %>%
  group_by(account_id, type) %>%
  summarise(
    count = n()
  ) 
`summarise()` has grouped output by 'account_id'. You can override using the `.groups` argument.
junior_card_transactions_2
NA
NA
NA

#zuerst durchschnitt pro gender berechnen und dann mean pro gender angeben

junior_type_sum <- junior_card_transactions$type %>%
  summary()

classic_type_sum <- classic_card_transactions$type %>%
  summary()

gold_type_sum <- gold_card_transactions$type %>%
  summary()

print('junior_type')
[1] "junior_type"
junior_type_sum
            credit         withdrawal withdrawal in cash 
             14681              20849                809 
print('classic_type')
[1] "classic_type"
classic_type_sum
            credit         withdrawal withdrawal in cash 
             58985              96724               4150 
print('gold_type')
[1] "gold_type"
gold_type_sum
            credit         withdrawal withdrawal in cash 
              9333              15803                604 
#Na untersuchen juniorcard
junior_card_transactions_na <- filter(junior_card_transactions, is.na(type)) 

junior_card_transactions_na_sum <- junior_card_transactions_na$operation %>%
  summary()
junior_card_transactions_na_sum
collection from other bank     credit card withdrawal 
                         0                          0 
            credit in cash   remittance to other bank 
                         0                          0 
        withdrawal in cash 
                         0 
#na untersuchen classic card
classic_card_transactions_na <- filter(classic_card_transactions, is.na(type)) 

classic_card_transactions_na_sum <- classic_card_transactions_na$operation %>%
  summary()
classic_card_transactions_na_sum
collection from other bank     credit card withdrawal 
                         0                          0 
            credit in cash   remittance to other bank 
                         0                          0 
        withdrawal in cash 
                         0 
#na untersuchen gold card
gold_card_transactions_na <- filter(gold_card_transactions, is.na(type)) 
client_gender <-ggplot(
  client, aes(x = gender, fill = gender))+
  geom_bar()+
  ggtitle('\nClients spread on gender\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )+
  labs( y= '\nNumber of Clients\n', x = '\nGender\n')
client_gender

The general information of the Age of the clients is a good base information as well.

client_age <- ggplot(
  client, aes(x = age,colour = gender))+
  # geom_bar(alpha = 0.5)+
  geom_density()+
  ggtitle('\nClientspread on age, separated by gender\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )+
  labs( y= '\ndensity\n', x = '\nAge\n')
  
client_age

card_type <- ggplot(
  card, aes(x = type, fill = type))+
  geom_bar()+
  ggtitle('\nSpread of card types\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
    )
  
card_type



gold_card_transactions_na_sum <- gold_card_transactions_na$operation %>%
  summary()
gold_card_transactions_na_sum
collection from other bank     credit card withdrawal 
                         0                          0 
            credit in cash   remittance to other bank 
                         0                          0 
        withdrawal in cash 
                         0 

junior_trans_viz <- ggplot(junior_card_transactions, aes( x = type, fill = gender))+
  geom_bar(position = 'dodge')+
  ggtitle('\nCredit compared to withdrawals Junior Card\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
  )
junior_trans_viz





classic_trans_viz <- ggplot(classic_card_transactions, aes( x = type, fill = gender))+
  geom_bar(position = 'dodge')+
  ggtitle('\nCredit compared to withdrawals classic card\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
  )
classic_trans_viz


gold_trans_viz <- ggplot(gold_card_transactions, aes( x = type, fill = gender))+
  geom_bar(position = 'dodge')+
  ggtitle('\nCredit compared to withdrawals gold card\n')+
  theme(
    plot.title = element_text(hjust = 0.5)
  )
gold_trans_viz

df_client_disp = client %>% full_join(disp, by ="client_id") %>%
  select(-district_id, -birth_number, -birthday)
df_account_client_disp = account %>% full_join(df_client_disp, by = "account_id")

str(df_account_client_disp)
'data.frame':   5369 obs. of  10 variables:
 $ account_id : int  576 576 3818 3818 704 704 2378 2632 1972 1539 ...
 $ district_id: int  55 55 74 74 55 55 16 24 77 1 ...
 $ frequency  : chr  "monthly issuance" "monthly issuance" "monthly issuance" "monthly issuance" ...
 $ date_ymd   : Date, format: "1993-01-01" "1993-01-01" ...
 $ client_id  : int  692 693 4601 4602 844 845 2873 3177 2397 1866 ...
 $ month      : int  51 3 4 54 1 51 53 NA 7 56 ...
 $ gender     : Factor w/ 2 levels "f","m": 1 2 2 1 2 1 1 2 2 1 ...
 $ age        : num  61 62 62 63 52 44 22 59 79 55 ...
 $ disp_id    : int  692 693 4601 4602 844 845 2873 3177 2397 1866 ...
 $ type       : Factor w/ 2 levels "OWNER","DISPONENT": 1 2 1 2 1 2 1 1 1 1 ...
summary(df_account_client_disp)
   account_id     district_id    frequency            date_ymd         
 Min.   :    1   Min.   : 1.0   Length:5369        Min.   :1993-01-01  
 1st Qu.: 1178   1st Qu.:14.0   Class :character   1st Qu.:1993-12-19  
 Median : 2349   Median :38.0   Mode  :character   Median :1996-01-03  
 Mean   : 2767   Mean   :37.3                      Mean   :1995-08-05  
 3rd Qu.: 3526   3rd Qu.:60.0                      3rd Qu.:1996-11-03  
 Max.   :11382   Max.   :77.0                      Max.   :1997-12-29  
                                                                       
   client_id         month       gender        age          disp_id     
 Min.   :    1   Min.   : 1.00   f:2645   Min.   :10.0   Min.   :    1  
 1st Qu.: 1418   1st Qu.: 6.00   m:2724   1st Qu.:29.0   1st Qu.: 1418  
 Median : 2839   Median :51.00            Median :43.0   Median : 2839  
 Mean   : 3359   Mean   :33.18            Mean   :43.8   Mean   : 3337  
 3rd Qu.: 4257   3rd Qu.:57.00            3rd Qu.:57.0   3rd Qu.: 4257  
 Max.   :13998   Max.   :62.00            Max.   :86.0   Max.   :13690  
                 NA's   :441                                            
        type     
 OWNER    :4500  
 DISPONENT: 869  
                 
                 
                 
                 
                 
nrow(df_account_client_disp)
[1] 5369
#density plot, women and men separated
df_account_client_disp %>% ggplot(aes(x = age, color = gender)) +
    geom_density(size = 1) + xlab('Age of clients')

#turning points in age
#in general
nr1 <- df_account_client_disp %>%
  filter(age == 16) %>%
  nrow()
nr1
[1] 30
nr2 <- df_account_client_disp %>%
  filter(age == 17) %>%
  nrow()
nr2
[1] 94
nr3 <- df_account_client_disp %>%
  filter(age == 58) %>%
  nrow()
nr3
[1] 104
nr4 <- df_account_client_disp %>%
  filter(age == 59) %>%
  nrow()
nr4
[1] 71
nr5 <- df_account_client_disp %>%
  filter(age == 79) %>%
  nrow()
nr5
[1] 46
nr6 <- df_account_client_disp %>%
  filter(age == 80) %>%
  nrow()
nr6
[1] 5
#turning points in age
#for women
df_account_client_disp_w <- df_account_client_disp %>%
  filter(gender == 'f')

nrw1 <- df_account_client_disp_w %>%
  filter(age == 16) %>%
  nrow()
nrw1
[1] 12
nrw2 <- df_account_client_disp_w %>%
  filter(age == 17) %>%
  nrow()
nrw2
[1] 49
nrw3 <- df_account_client_disp_w %>%
  filter(age == 58) %>%
  nrow()
nrw3
[1] 54
nrw4 <- df_account_client_disp_w %>%
  filter(age == 59) %>%
  nrow()
nrw4
[1] 26
nrw5 <- df_account_client_disp_w %>%
  filter(age == 79) %>%
  nrow()
nrw5
[1] 22
nrw6 <- df_account_client_disp_w %>%
  filter(age == 80) %>%
  nrow()
nrw6
[1] 2
#for men
df_account_client_disp_m <- df_account_client_disp %>%
  filter(gender == 'm')

nrm1 <- df_account_client_disp_m %>%
  filter(age == 16) %>%
  nrow()
nrm1
[1] 18
nrm2 <- df_account_client_disp_m %>%
  filter(age == 17) %>%
  nrow()
nrm2
[1] 45
nrm3 <- df_account_client_disp_m %>%
  filter(age == 62) %>%
  nrow()
nrm3
[1] 53
nrm4 <- df_account_client_disp_m %>%
  filter(age == 63) %>%
  nrow()
nrm4
[1] 27
nrm5 <- df_account_client_disp_m %>%
  filter(age == 79) %>%
  nrow()
nrm5
[1] 24
nrm6 <- df_account_client_disp_m %>%
  filter(age == 80) %>%
  nrow()
nrm6
[1] 3
#bar chart, one bar for each age
df_account_client_disp %>% ggplot(aes(x = age)) + geom_bar() + scale_fill_brewer(palette = "Paired") 


#bar chart, women and men separated, one bar for each age
df_account_client_disp %>% ggplot(aes(x = age, fill = gender)) + geom_bar(position = 'dodge') +
         scale_fill_brewer(palette = "Paired") + xlab('Age of clients')


#stacked bar chart, women and men separated, one bar for each age
df_account_client_disp %>% ggplot(aes(x = age, fill = gender)) + geom_bar() +
         scale_fill_brewer(palette = "Paired") + xlab('Age of clients')


#two bar charts, women and men separated, each age one bar
df_account_client_disp %>% ggplot(aes(x = age, fill = gender)) + geom_bar() +
         scale_fill_brewer(palette = "Paired") + facet_wrap(~ gender) + xlab('Age of clients')


#coordination flipped bar chart, omen and men separated, one bar for each age
df_account_client_disp %>% ggplot(aes(x = age, fill = gender)) + geom_bar() + coord_flip() +
         scale_fill_brewer(palette = "Paired") + xlab('Age of clients')


#coordination flipped bar chart, omen and men separated, one bar for each age, in percentage
df_account_client_disp %>% ggplot(aes(x = age, fill = gender)) + geom_bar(position = 'fill') +
  coord_flip() + scale_fill_brewer(palette = "Paired") + xlab('Age of clients')

#order the clients by youngest and oldest, youngest is 10, oldest is 86
#group all the clients in 7 different groups
df_account_client_disp <- df_account_client_disp %>%
  mutate(age_grouped = case_when(
    age <= 16 ~ '1-16',
    age <= 32 ~ '17-32',
    age <= 48 ~ '33-48',
    age <= 64 ~ '49-64',
    age <= 72 ~ '65-72',
    age <= 86 ~ '73-86',
    TRUE ~ 'not known'
  ))

#factor the groups
df_account_client_disp <- df_account_client_disp %>% 
  mutate(age_grouped = as_factor(age_grouped))

#order the new age column in a determined way
df_account_client_disp$age3 <- 
  ordered(df_account_client_disp$age_grouped, levels = c('1-16', '17-32', '33-48', '49-64', '65-72',
                                                         '73-86'))
#bar chart, all clients in 7 groups
df_account_client_disp %>% ggplot(aes(x = factor(age_grouped))) + geom_bar() +
         scale_fill_brewer(palette = "Paired") + xlab('Age of clients')


#two bar charts, women and men separated, 7 groups 
df_account_client_disp %>% ggplot(aes(x = age_grouped, fill = gender)) + geom_bar() +
         scale_fill_brewer(palette = "Paired") + facet_wrap(~ gender)+ xlab('Age of clients')


#bar chart, women and men separated, 7 groups 
df_account_client_disp %>% ggplot(aes(x = age_grouped, fill = gender)) + geom_bar(position = 'dodge') +
         scale_fill_brewer(palette = "Paired") + xlab('Age of clients')


#stacked bar chart, women and men separated, 7 groups 
df_account_client_disp %>% ggplot(aes(x = age_grouped, fill = gender)) + 
  geom_bar() + scale_fill_brewer(palette = "Paired") + xlab('Age of clients')


#reorder the age3 column to ascending
df_account_client_disp <- df_account_client_disp %>%
  mutate(age3 = fct_reorder(age_grouped, desc(age_grouped))) 

#coordination flipped bar chart, women and men separated, 7 groups 
df_account_client_disp %>% ggplot(aes(x = age_grouped, fill = gender)) + 
  geom_bar() + scale_fill_brewer(palette = "Paired") +
  coord_flip() + xlab('Age of clients')


#coordination flipped bar chart, women and men separated, 7 groups, in percentage
df_account_client_disp %>% ggplot(aes(x = age_grouped, fill = gender)) + 
  geom_bar(position = 'fill') + scale_fill_brewer(palette = "Paired") + coord_flip() + 
  xlab('Age of clients') + ylab('Density') 

LS0tCnRpdGxlOiAiMURhIENyb3NzLXNlbGxpbmcgaW4gYmFua2luZyBjaGFsbGVuZ2UgLSBBbGVzc2lhIC8gSmVubmkiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KV2UgYXJlIHdvcmtpbmcgd2l0aCBhIGRhdGFzZXQgZnJvbSBhIGN6ZWNoIGJhbmsuIAoKQmVsb3cgd2UgaGF2ZSBsb2FkZWQgYWxsIHRoZSBwYWNrYWdlcyBhbmQgZGF0YSBhcyB3ZWxsIGFzIG9yZ2FuaXplZCBhbmQgc3R1cmN0dXJlZCBpdCBzbyB3ZSBjYW4gd29yayB3aXRoIGl0Lgpsb2FkaW5nIGFsbCBwYWNrYWdlcyBhbmQgZGF0YQpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkodGlkeW1vZGVscykKbGlicmFyeShnZ21vc2FpYykKbGlicmFyeShnZ2FsbHV2aWFsKQpsaWJyYXJ5KHJwYXJ0KQpsaWJyYXJ5KHJwYXJ0LnBsb3QpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KHVzZXRoaXMpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKYGBgCgpgYGB7cn0KCmFjY291bnQgPC0gcmVhZC5jc3YoJy4vYWNjb3VudC5jc3YnLCBzZXAgPSAiOyIpCmNhcmQgPC0gcmVhZC5jc3YoJy4vY2FyZC5jc3YnLCBzZXAgPSAiOyIpCmNsaWVudCA8LSByZWFkLmNzdignLi9jbGllbnQuY3N2Jywgc2VwID0gIjsiKQpkaXNwIDwtIHJlYWQuY3N2KCcuL2Rpc3AuY3N2Jywgc2VwID0gIjsiKQpkaXN0cmljdCA8LSByZWFkLmNzdignLi9kaXN0cmljdC5jc3YnLCBzZXAgPSAnOycpCmxvYW4gPC0gcmVhZC5jc3YoJy4vbG9hbi5jc3YnLCBzZXAgPSAiOyIpCm9yZGVyIDwtIHJlYWQuY3N2KCcuL29yZGVyLmNzdicsIHNlcCA9ICI7IikKdHJhbnMgPC0gcmVhZC5jc3YoJy4vdHJhbnMuY3N2Jywgc2VwID0gIjsiKQoKYGBgCgpjbGVhbi9vcmdhbml6ZSBhY2NvdW50CmBgYHtyfQoKI3JlZm9ybWF0IGRhdGUKYWNjb3VudCRkYXRlX3ltZCA8LSBmb3JtYXQoYXMuRGF0ZShhcy5jaGFyYWN0ZXIoYWNjb3VudCRkYXRlKSwgIiV5JW0lZCIpLCAiMTkleS8lbS8lZCIpIAoKYWNjb3VudCA8LSBhY2NvdW50ICU+JQogIHNlbGVjdCgtZGF0ZSkKCiNmYWN0b3JpemUgdmFyaWFibGVzCmFjY291bnQgPC0gYWNjb3VudCAlPiUgCiAgbXV0YXRlIChmcmVxdWVuY3kgPSBhc19mYWN0b3IoZnJlcXVlbmN5KSwgCiAgICAgICAgICBkYXRlX3ltZCA9IGFzLkRhdGUoZGF0ZV95bWQpCiAgICAgICAgICApICU+JQogIG11dGF0ZShmcmVxdWVuY3kgPSBjYXNlX3doZW4oCiAgICBmcmVxdWVuY3kgPT0gJ1BPUExBVEVLIE1FU0lDTkUnIH4gJ21vbnRobHkgaXNzdWFuY2UnLAogICAgZnJlcXVlbmN5ID09ICdQT1BMQVRFSyBUWURORScgfiAnd2Vla2x5IGlzc3VhbmNlJywKICAgIGZyZXF1ZW5jeSA9PSAnUE9QTEFURUsgUE8gT0JSQVRVJyB+ICdpc3N1YW5jZSBhZnRlciB0cmFuc2FjdGlvbicKICApKQoKYGBgCgpjbGVhbi9vcmdhbml6ZSBjYXJkCmBgYHtyfQoKI3JlZm9ybWF0IGRhdGUKY2FyZCRpc3N1ZWRfZGF0ZSA8LSBmb3JtYXQoYXMuRGF0ZShhcy5jaGFyYWN0ZXIoY2FyZCRpc3N1ZWQpLCAiJXklbSVkIiksICIxOSV5LyVtLyVkIikKCiNmYWN0b3JpemUgdmFyaWFibGVzCmNhcmQgPC0gY2FyZCAlPiUKICBtdXRhdGUodHlwZSA9IGFzX2ZhY3Rvcih0eXBlKSwgCiAgICAgICAgIGlzc3VlZF9kYXRlID0gYXMuRGF0ZShpc3N1ZWRfZGF0ZSkKICAgICAgICAgKQogIApgYGAKCmNsZWFuL29yZ2FuaXplIGNsaWVudCAoRGFuaSBmcmFnZW4pCmBgYHtyfQoKI3JlZm9ybWF0IGJpcnRoX251bWJlcgoKY2xpZW50IDwtIGNsaWVudCAlPiUKICBtdXRhdGUobW9udGggPSBzdWJzdHIoYmlydGhfbnVtYmVyLCAzLCA0KSkgJT4lCiAgbXV0YXRlKG1vbnRoID0gc3RydG9pKG1vbnRoKSkKCmNsaWVudCA8LSBjbGllbnQgJT4lCiAgbXV0YXRlKGdlbmRlciA9IGNhc2Vfd2hlbigKICAgIG1vbnRoID4gMTIgfiAnZicsCiAgICBUUlVFIH4gJ20nKQogICkKCmNsaWVudCA8LSBjbGllbnQgJT4lCiAgbXV0YXRlKGJpcnRoX251bWJlciA9IGFzLm51bWVyaWMoYmlydGhfbnVtYmVyKSkKCmNsaWVudCA8LSBjbGllbnQgJT4lCiAgbXV0YXRlKGJpcnRoX251bWJlciA9IGNhc2Vfd2hlbigKICAgIG1vbnRoID4gMTIgfiBiaXJ0aF9udW1iZXIgLSA1MDAwLAogICAgVFJVRSB+IGJpcnRoX251bWJlcikKICApCgoKCmNsaWVudCRiaXJ0aGRheSA8LSBmb3JtYXQoYXMuRGF0ZShhcy5jaGFyYWN0ZXIoY2xpZW50JGJpcnRoX251bWJlciksICIleSVtJWQiKSwgIjE5JXkvJW0vJWQiKQoKI2ZhY3Rvcml6ZSB2YXJpYWJsZXMKY2xpZW50IDwtIGNsaWVudCAlPiUKICBtdXRhdGUoZGlzdHJpY3RfaWQgPSBhc19mYWN0b3IoZGlzdHJpY3RfaWQpLCAKICAgICAgICAgZ2VuZGVyID0gYXNfZmFjdG9yKGdlbmRlciksCiAgICAgICAgIGJpcnRoZGF5ID0gYXMuRGF0ZShiaXJ0aGRheSkKICAgICAgICAgKQpwcm9qZWN0X2RhdGUgPSAnMTk5OC8xLzEnCgpsaWJyYXJ5KGVlcHRvb2xzKQp4IDwtIGFzLkRhdGUoYygiMTk5OC0wMS0wMSIpKQoKCmNsaWVudCRhZ2UgPC0gZmxvb3IoYWdlX2NhbGMoYXMuRGF0ZShjbGllbnQkYmlydGhkYXkpLHgsIHVuaXRzID0gInllYXJzIikpCgpsaWJyYXJ5KGVlcHRvb2xzKQp4IDwtIGFzLkRhdGUoYygiMTk5OC0wMS0wMSIpKQoKCmNsaWVudCRhZ2UgPC0gZmxvb3IoYWdlX2NhbGMoYXMuRGF0ZShjbGllbnQkYmlydGhkYXkpLHgsIHVuaXRzID0gInllYXJzIikpCgpgYGAKCmJpcnRoZGF5IHByb3BlciBzaGFwZQpgYGB7cn0KY2xpZW50IDwtIGNsaWVudCAlPiUKICBtdXRhdGUoCiAgICBiaXJ0aF9udW1iZXIgPSBiaXJ0aF9udW1iZXIgKyAxOTAwMDAwMAogICkKCmBgYAoKY2xlYW4vb3JnYW5pemUgZGlzcApgYGB7cn0KCiNmYWN0b3JpemUgdmFyaWFibGVzCmRpc3AgPC0gZGlzcCAlPiUKICBtdXRhdGUodHlwZSA9IGFzX2ZhY3Rvcih0eXBlKQogICAgICAgICApCgpgYGAKCmNsZWFuL29yZ2FuaXplIGRpc3RyaWN0CmBgYHtyfQoKI3JlbmFtZSBjb2x1bnMKbmFtZXMoZGlzdHJpY3QpIDwtIGMoJ2Rpc3RyaWN0X2lkJywgJ2Rpc3RyaWN0X25hbWUnLCAncmVnaW9uJywgJ2hhYml0YW50cycsICdtdW5pY2lwYWxpdGllczw0OTknLAogICAgICAgICAgICAgICAgICAgICAnbXVuaWNpcGFsaXRpZXM8NTAwLTEwMDAnLCAnbXVuaWNpcGFsaXRpZXM8MjAwMC05OTk5JywgJ211bmljaXBhbGl0aWVzPjEwMDAwJywgJ2NpdGllcycsCiAgICAgICAgICAgICAgICAgICAgICdyYXRpb191cmJhbl9pbmhhYml0YW50cycsICdhdmVyYWdlX3NhbGFyeScsICd1bmVtcGxveW1lbnRfcmF0ZV8xOTk1JywgJ3VuZW1wbG95bWVudF9yYXRlXzE5OTYnLAogICAgICAgICAgICAgICAgICAgICAnZW50ZXJwcmVuZXVyc19wZXJfMTAwMCcsICdjcmltZXNfMTk5NScsICdjcmltZXNfMTk5NicpCgojZmFjdG9yaXplIHZhcmlhYmxlcwpkaXN0cmljdCA8LSBkaXN0cmljdCAlPiUKICBtdXRhdGUoZGlzdHJpY3RfbmFtZSA9IGFzX2ZhY3RvcihkaXN0cmljdF9uYW1lKSwgcmVnaW9uID0gYXNfZmFjdG9yKHJlZ2lvbikpCgojY2hhbmdlIGRhdGF0eXBlIHRvIG51bWVyaWMvaW50CmRpc3RyaWN0IDwtIGRpc3RyaWN0ICU+JSAKICBtdXRhdGUodW5lbXBsb3ltZW50X3JhdGVfMTk5NSA9IGFzLm51bWVyaWModW5lbXBsb3ltZW50X3JhdGVfMTk5NSksIAogICAgICAgICBlbnRlcnByZW5ldXJzX3Blcl8xMDAwID0gc3RydG9pKGVudGVycHJlbmV1cnNfcGVyXzEwMDApLCAKICAgICAgICAgY3JpbWVzXzE5OTUgPSBzdHJ0b2koY3JpbWVzXzE5OTUpCiAgICAgICAgICkKCiNzdHIoZGlzdHJpY3QpCgpgYGAKCmNsZWFuL29yZ2FuaXplIGxvYW4KYGBge3J9CgojcmVmb3JtYXQgZGF0ZQpsb2FuJGRhdGVfaXNzdWVkIDwtIGZvcm1hdChhcy5EYXRlKGFzLmNoYXJhY3Rlcihsb2FuJGRhdGUpLCAiJXklbSVkIiksICIxOSV5LyVtLyVkIikKbG9hbiA8LSBsb2FuICU+JQogIHNlbGVjdCgtZGF0ZSkKCgojZmFjdG9yaXplIHZhcmlhYmxlcwpsb2FuIDwtIGxvYW4gJT4lCiAgbXV0YXRlKGR1cmF0aW9uID0gYXNfZmFjdG9yKGR1cmF0aW9uKSwgCiAgICAgICAgIHN0YXR1cyA9IGFzX2ZhY3RvcihzdGF0dXMpLAogICAgICAgICBkYXRlX2lzc3VlZCA9IGFzLkRhdGUoZGF0ZV9pc3N1ZWQpCiAgICAgICAgICkKCmBgYAoKY2xlYW4vb3JnYW5pemUgb3JkZXIKYGBge3J9CgojZmFjdG9yaXplIHZhcmlhYmxlcwpvcmRlciA8LSBvcmRlciAlPiUKICBtdXRhdGUoYmFua190byA9IGFzX2ZhY3RvcihiYW5rX3RvKSwgCiAgICAgICAgIGtfc3ltYm9sID0gYXNfZmFjdG9yKGtfc3ltYm9sKQogICAgICAgICApCgoKb3JkZXIgPC0gb3JkZXIgJT4lCiAgbXV0YXRlKGtfc3ltYm9sID0gY2FzZV93aGVuKAogICAga19zeW1ib2wgPT0gJ1BPSklTVE5FJyB+ICdpc3N1cmFuY2UgcGF5bWVudCcsCiAgICBrX3N5bWJvbCA9PSAnU0lQTycgfiAnaG91c2Vob2xkJywKICAgIGtfc3ltYm9sID09ICdMRUFTSU5HJyB+ICdsZWFzaW5nJywKICAgIGtfc3ltYm9sID09ICdVVkVSJyB+ICdsb2FuIHBheW1lbnQnCiAgKQogICAgCiAgKQojc3RyKG9yZGVyKQpgYGAKCmNsZWFuL29yZ2FuaXplIHRyYW5zCmBgYHtyfQoKI3JlZm9ybWF0IGRhdGUKdHJhbnMkZGF0ZV9kbXkgPC0gZm9ybWF0KGFzLkRhdGUoYXMuY2hhcmFjdGVyKHRyYW5zJGRhdGUpLCAiJXklbSVkIiksICIxOSV5LyVtLyVkIikKCnRyYW5zIDwtIHRyYW5zICU+JQogIHNlbGVjdCgtZGF0ZSkKCiNmYWN0b3JpemUgdmFyaWFibGVzCnRyYW5zIDwtIHRyYW5zICU+JQogIG11dGF0ZSh0eXBlID0gYXNfZmFjdG9yKHR5cGUpLAogICAgICAgICBvcGVyYXRpb24gPSBhc19mYWN0b3Iob3BlcmF0aW9uKSwKICAgICAgICAga19zeW1ib2wgPSBhc19mYWN0b3Ioa19zeW1ib2wpLAogICAgICAgICBkYXRlX2RteSA9IGFzLkRhdGUoZGF0ZV9kbXkpCiAgICAgICAgICkKCnRyYW5zIDwtIHRyYW5zICU+JQogIG11dGF0ZSh0eXBlID0gY2FzZV93aGVuKAogICAgdHlwZSA9PSAnUFJJSkVNJyB+ICdjcmVkaXQnLAogICAgdHlwZSA9PSAnVllEQUonIH4gJ3dpdGhkcmF3YWwnLAogICAgdHlwZSA9PSAnVllCRVInIH4gJ3dpdGhkcmF3YWwgaW4gY2FzaCcKICApKSAlPiUKICBtdXRhdGUob3BlcmF0aW9uID0gY2FzZV93aGVuKAogICAgb3BlcmF0aW9uID09ICdWWUJFUiBLQVJUT1UnIH4gJ2NyZWRpdCBjYXJkIHdpdGhkcmF3YWwnLAogICAgb3BlcmF0aW9uID09ICdWS0xBRCcgfiAnY3JlZGl0IGluIGNhc2gnLAogICAgb3BlcmF0aW9uID09ICdQUkVWT0QgWiBVQ1RVJyB+ICdjb2xsZWN0aW9uIGZyb20gb3RoZXIgYmFuaycsCiAgICBvcGVyYXRpb24gPT0gJ1ZZQkVSJyB+ICd3aXRoZHJhd2FsIGluIGNhc2gnLAogICAgb3BlcmF0aW9uID09ICdQUkVWT0QgTkEgVUNFVCcgfiAncmVtaXR0YW5jZSB0byBvdGhlciBiYW5rJwogICkpICU+JQogIG11dGF0ZShrX3N5bWJvbCA9IGNhc2Vfd2hlbigKICAgIGtfc3ltYm9sID09ICdQT0pJU1RORScgfiAnaW5zdXJyYW5jZSBwYXltZW50JywKICAgIGtfc3ltYm9sID09ICdTTFVaQlknIH4gJ3BheW1lbnQgZm9yIHN0YXRlbWVudCcsCiAgICBrX3N5bWJvbCA9PSAnVVJPSycgfiAnaW50ZXJlc3QgY3JlZGl0ZWQnLAogICAga19zeW1ib2wgPT0gJ1NJUE8nIH4gJ2hvc2Vob2xkJywKICAgIGtfc3ltYm9sID09ICdEVUNIT0QnIH4gJ29sZC1hZ2UgcGVuc2lvbicsCiAgICBrX3N5bWJvbCA9PSAnVVZFUicgfiAnbG9hbiBwYXltZW50JwogICkpCgoKYGBgCgpCcmluZyB0b2dldGhlciBjbGllbnQgYW5kIGRpc3AKYGBge3J9CmNsaWVudF9kaXNwIDwtIGZ1bGxfam9pbigKICAgIGRpc3AsY2xpZW50LCBieSA9ICdjbGllbnRfaWQnCikgCgpjbGllbnRfZGlzcCA8LSBmdWxsX2pvaW4oCiAgY2xpZW50X2Rpc3AsIGNhcmQsIGJ5ID0gJ2Rpc3BfaWQnCikKCmNsaWVudF9kaXNwIDwtIGNsaWVudF9kaXNwICU+JQogIHJlbmFtZSgKICAgIHR5cGVfY2xpZW50ID0gdHlwZS54LAogICAgdHlwZV9jYXJkID0gdHlwZS55LAogICAgY2FyZF9pc3N1ZWQgPSBpc3N1ZWRfZGF0ZQogICkgJT4lCiAgc2VsZWN0KAogICAgLSBiaXJ0aF9udW1iZXIsCiAgICAtIG1vbnRoLAogICAgLSBpc3N1ZWQKICApCgoKI2dlbmRlciBjb3VudCBhbGxlciBjbGllbnRzCmdlbmRlcl9ncm91cCA8LSBjbGllbnRfZGlzcCAlPiUKIGNvdW50KGdlbmRlcikKZ2VuZGVyX2dyb3VwCgojdHlwZSBjb3VudCBhbGxlciBjbGllbnRzCmdlbl9jbGllbnRfZ3JvdXAgPC0gY2xpZW50X2Rpc3AgJT4lCiAgY291bnQodHlwZV9jbGllbnQpCmdlbl9jbGllbnRfZ3JvdXAKCiNnZW5kZXIgY291bnQgbmFjaCB0eXBlCmdlbl9jbGllbnRfdGVzdDwtIGNsaWVudF9kaXNwICU+JQogIGdyb3VwX2J5KGdlbmRlcikgJT4lCiAgY291bnQodHlwZV9jbGllbnQpCmdlbl9jbGllbnRfdGVzdAoKI2hlcmF1c2ZpbmRlbiBvYiAxIGNsaWVudCBtZWhyZXJlIGFjY291bnRzCgojIGdlbmRlciBzcHJlYWQgY3plY2sgcmVwdWJsaWsgMTk5OCBmZW1hbGUgNTEuMzclIGh0dHBzOi8vZGF0YS53b3JsZGJhbmsub3JnL2luZGljYXRvci9TUC5QT1AuVE9UTC5GRS5aUz9lbmQ9MTk5OCZsb2NhdGlvbnM9Q1omc3RhcnQ9MTk5OApgYGAKCgoKRnJhZ2VzdGVsbHVuZyBSZWNoZXJjaGUgSmVubmkKClF1aWNrIG92ZXJ2aWV3IHJlc2VhcmNoIHRvIGdldCB0byBrbm93IHRoZSBvdXRsaW5lcyBvZiB0aGUgZGF0YXNldCBhbmQgZGVjaWRlIHdoZXJlIHRvIGdvIGRlZXBlci4KCgpGaXJzdCBpIHdhbnRlZCB0byBzZWUgdGhlIGdlbmRlcmRpc3RyaWJ1dGlvbiBvZiB0aGUgY2xpZW50cy4KCkFzIHdlIGNhbiBzZWUgaW4gdGhlIFBsb3QgYmVsb3csIHRoZXJlIGFyZSBzbGlnaHRseSBsZXNzIHdvbWVuIHRoYW4gbWFuLCBidXQgb3ZlciBhbGwgdGhlIGdlbmRlciBpcyBwcmV0dHkgYmFsYW5jZWQgb3V0LgpgYGB7cn0KY2xpZW50X2dlbmRlcl9qIDwtZ2dwbG90KAogIGNsaWVudCwgYWVzKHggPSBnZW5kZXIsIGZpbGwgPSBnZW5kZXIpKSsKICBnZW9tX2JhcigpKwogIGdndGl0bGUoJ1xuQ2xpZW50cyBzcHJlYWQgb24gZ2VuZGVyXG4nKSsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpCiAgICApKwogIGxhYnMoIHk9ICdcbk51bWJlciBvZiBDbGllbnRzXG4nLCB4ID0gJ1xuR2VuZGVyXG4nKQpjbGllbnRfZ2VuZGVyX2oKCmBgYAoKYGBge3J9CmNsaWVudF9vd25lcl9qIDwtZ2dwbG90KAogIGNsaWVudF9kaXNwLCBhZXMoeCA9IHR5cGVfY2xpZW50LGZpbGwgPSBnZW5kZXIgKSkrCiAgZ2VvbV9iYXIocG9zaXRpb24gPSdkb2RnZScpKwogIGdndGl0bGUoJ1xuT3duZXIvRGlzcG9uZW50IHNwcmVhZCBvbiBnZW5kZXJcbicpKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkKICAgICkrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IC4uY291bnQuLiksIHN0YXQgPSAiY291bnQiLCBwb3NpdGlvbiA9ICBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIHZqdXN0ID0gMikrCiAgbGFicyggeT0gJ1xuTnVtYmVyIG9mIENsaWVudHNcbicsIHggPSAnXG5HZW5kZXJcbicpCmNsaWVudF9vd25lcl9qCgojd2VpdGVyIHVudGVyc3VjaGVuLCB3ZXIgbWFjaHQgZGllIMOcYmVyd2Vpc3VuZ2VuIHVuZCBhbHRlcnNncnVwcGVuCiNjaGVjayBtaXQgY291bnQKCnByaW50KGNvdW50KGNsaWVudF9kaXNwKSkKCm93bmVyX3RvdGFsIDwtIHN1bShjbGllbnRfZGlzcCR0eXBlX2NsaWVudD09ICdPV05FUicpCmNhdCgnVG90YWwgT1dORVI6Jywgb3duZXJfdG90YWwpIAoKZGlzcG9fdG90YWwgPC0gc3VtKGNsaWVudF9kaXNwJHlwZV9jbGllbnQ9PSAnRElTUE9ORU5UJykKY2F0KCdUb3RhbCBESVNQT05FTlQ6ICcsIGRpc3BvX3RvdGFsKQoKZmVtYWxlX2NsaWVudCA8LSBzdW0oY2xpZW50X2Rpc3AkZ2VuZGVyID09ICdmJykKY2F0KCdUb3RhbCBmZW1hbGUgY2xpZW50czogJyxmZW1hbGVfY2xpZW50KQoKbWFsZV9jbGllbnQgPC0gc3VtKGNsaWVudF9kaXNwJGdlbmRlciA9PSAnbScpCmNhdCgnVG90YWwgbWFsZSBjbGllbnRzOiAnLGZlbWFsZV9jbGllbnQpCgpwcmludCgnVGhlcmUgaXMgYW4gZXF1YWwgYW1vdW50IG9mIG1hbGUgYW5kIGZlbWFsZSBjbGllbnRzLiBUaGF0IGlzIHZlcnkgc3VycHJpc2luZy4gV2Ugd2lsbCBoYXZlIGEgZGVlcGVyIGxvb2sgYXQgdGhpcy4nKQojIGRhIHN0aW1tdCBldHdhcyBuaWNodC4gQmVpIGNsaWVudHMgc2FndHMgZXMgc2luZCA1MzY5IG9ic2VydmF0aW9uZW4sIHdlbm4gbWFubiBuYWNoIGdlbmRlciBvZHJuZXQgc2luZCBpbW1lciB6dSB2aWVsZSBkYXMgZXJzdGUgZ2VzY2hsZWNodC4/Pz8/CgoKICAgICAgCgpgYGAKCgpUaGUgZ2VuZXJhbCBpbmZvcm1hdGlvbiBvZiB0aGUgQWdlIG9mIHRoZSBjbGllbnRzIGlzIGEgZ29vZCBiYXNlIGluZm9ybWF0aW9uIGFzIHdlbGwuCgpXZSBnYW4gc2VlIGluIHRoZSBwbG90IGJlbG93IG1vc3QgY2xpZW50cyBhcmUgYmV0d2VlbiAyMCBhbmQgNTUgeWVhcnMgb2xkLiAKCmBgYHtyfQpjbGllbnRfYWdlX2ogPC0gZ2dwbG90KAogIGNsaWVudCwgYWVzKHggPSBhZ2UsIGNvbG91ciA9IGdlbmRlcikpKwogICNnZW9tX2JhcihhbHBoYSA9IDAuNSkrCiAgZ2VvbV9kZW5zaXR5KCkrCiAgZ2d0aXRsZSgnXG5DbGllbnRzcHJlYWQgb24gYWdlLCBzZXBhcmF0ZWQgYnkgZ2VuZGVyXG4nKSsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpCiAgICApKwogIGxhYnMoIHkgPSAnXG5kZW5zaXR5XG4nLCB4ID0gJ1xuQWdlXG4nKQogIApjbGllbnRfYWdlX2oKCmFnZV9jb3VudCA8LSBjbGllbnQgJT4lCiAgZ3JvdXBfYnkoZ2VuZGVyLCBhZ2UpICU+JQogIHN1bW1hcmlzZSgKICAgIGNvdW50ID0gbigpCiAgKQphZ2VfY291bnQKCgpjbGllbnRfYWdlX2psIDwtIGdncGxvdCgKICBhZ2VfY291bnQsIGFlcyh4ID0gYWdlLCBjb2xvdXIgPSBnZW5kZXIsIHkgPSBjb3VudCkpKwogICNnZW9tX2JhcihhbHBoYSA9IDAuNSkrCiAgIyBnZW9tX3BvaW50KCkrCiAgZ2VvbV9saW5lKCkrCiAgZ2d0aXRsZSgnXG5DbGllbnRzcHJlYWQgb24gYWdlLCBzZXBhcmF0ZWQgYnkgZ2VuZGVyXG4nKSsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpCiAgICApCmNsaWVudF9hZ2VfamwKCgpgYGAKCgoKCmBgYHtyfQpjYXJkX3R5cGVfaiA8LSBnZ3Bsb3QoCiAgY2FyZCwgYWVzKHggPSB0eXBlLCBmaWxsID0gdHlwZSkpKwogIGdlb21fYmFyKCkrCiAgZ2d0aXRsZSgnXG5TcHJlYWQgb2YgY2FyZCB0eXBlc1xuJykrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IC4uY291bnQuLiksIHN0YXQgPSAiY291bnQiLCBwb3NpdGlvbiA9ICBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIHZqdXN0ID0gMikrCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KQogICAgKQogIApjYXJkX3R5cGVfagoKY2FyZF90eXBlX2p4IDwtIGdncGxvdCgKICBjbGllbnRfZGlzcCwgYWVzKHggPSB0eXBlX2NsaWVudCwgZmlsbCA9IGdlbmRlcikpKwogIGdlb21fYmFyKHBvc2l0aW9uID0gJ2RvZGdlJykrCiAgZ2d0aXRsZSgnXG5TcHJlYWQgb2YgY2FyZCB0eXBlc1xuJykrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IC4uY291bnQuLiksIHN0YXQgPSAiY291bnQiLCBwb3NpdGlvbiA9ICBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIHZqdXN0ID0gMikrCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KQogICAgKQogIApjYXJkX3R5cGVfangKCmBgYAoKCmBgYHtyfQpjYXJkX3R5cGVfZ19qIDwtIGdncGxvdCgKICBjbGllbnRfZGlzcCwgYWVzKHggPSB0eXBlX2NhcmQsIGZpbGwgPSBnZW5kZXIpKSsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICdkb2RnZScpKwogIGdndGl0bGUoJ1xuU3ByZWFkIG9mIGNhcmQgdHlwZXNcbicpKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSAuLmNvdW50Li4pLCBzdGF0ID0gImNvdW50IiwgcG9zaXRpb24gPSAgcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCB2anVzdCA9IDIpKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkKICAgICkKICAKY2FyZF90eXBlX2dfagpgYGAKCmBgYHtyfQpjYXJkX3R5cGVfYWdlX2cgPC0gZ2dwbG90KAogIGNsaWVudF9kaXNwLCBhZXMoeCA9IGFnZSwgY29sb3VyID0gdHlwZV9jYXJkKSkrCiAgZ2VvbV9kZW5zaXR5KHBvc2l0aW9uID0gJ2RvZGdlJykrCiAgZ2d0aXRsZSgnXG5TcHJlYWQgb2YgY2FyZCB0eXBlc1xuJykrCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KQogICAgKQpjYXJkX3R5cGVfYWdlX2cKCmFnZV9jYXJkIDwtIGNsaWVudF9kaXNwICU+JQogIGdyb3VwX2J5KCB0eXBlX2NhcmQsIGFnZSApICU+JQogIHN1bW1hcmlzZSgKICAgIGNvdW50ID0gbigpCiAgKQphZ2VfY2FyZAoKY2FyZF90eXBlX2FnZSA8LSBnZ3Bsb3QoCiAgYWdlX2NhcmQsIGFlcyh4ID0gYWdlLCB5ID0gY291bnQsIGNvbG91ciA9IHR5cGVfY2FyZCkpKwogIGdlb21fbGluZShwb3NpdGlvbiA9ICdkb2RnZScpKwogIGdndGl0bGUoJ1xuU3ByZWFkIG9mIGNhcmQgdHlwZXNcbicpKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkKICAgICkKICAKY2FyZF90eXBlX2FnZQoKCmFnZV9jYXJkX20gPC0gZmlsdGVyKGNsaWVudF9kaXNwLCBnZW5kZXIgPT0gJ20nKQphZ2VfY2FyZF9tCgphZ2VfY2FyZF9mIDwtIGZpbHRlcihjbGllbnRfZGlzcCwgZ2VuZGVyID09ICdmJykKYWdlX2NhcmRfZgoKYWdlX2NhcmRfbSA8LSBhZ2VfY2FyZF9tICU+JQogIGdyb3VwX2J5KGFnZSwgdHlwZV9jYXJkKSAlPiUKICBzdW1tYXJpc2UoCiAgICBjb3VudCA9IG4oKQogICkgCgphZ2VfY2FyZF9mIDwtIGFnZV9jYXJkX2YgJT4lCiAgZ3JvdXBfYnkoYWdlLCB0eXBlX2NhcmQpICU+JQogIHN1bW1hcmlzZSgKICAgIGNvdW50ID0gbigpCiAgKSAKCgpjYXJkX3R5cGVfYWdlX20gPC0gZ2dwbG90KAogIGFnZV9jYXJkX20sIGFlcyh4ID0gYWdlLCB5ID0gY291bnQsIGNvbG91ciA9IHR5cGVfY2FyZCkpKwogIGdlb21fbGluZShwb3NpdGlvbiA9ICdkb2RnZScpKwogIGdndGl0bGUoJ1xuU3ByZWFkIG9mIGNhcmQgdHlwZXMgb2YgbWFsZSBjbGllbnRzXG4nKSsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpCiAgICApCiAgCmNhcmRfdHlwZV9hZ2VfbQoKY2FyZF90eXBlX2FnZV9mIDwtIGdncGxvdCgKICBhZ2VfY2FyZF9mLCBhZXMoeCA9IGFnZSwgeSA9IGNvdW50LCBjb2xvdXIgPSB0eXBlX2NhcmQpKSsKICBnZW9tX2xpbmUocG9zaXRpb24gPSAnZG9kZ2UnKSsKICBnZ3RpdGxlKCdcblNwcmVhZCBvZiBjYXJkIHR5cGVzIG9mIGZlbWFsZSBjbGllbnRzXG4nKSsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpCiAgICApCiAgCmNhcmRfdHlwZV9hZ2VfZgpgYGAKCgo8PDw8PDw8IEhFQUQKYGBge3J9CiMgZmlsdGVyIGJ5IGNhcmQsIG1ha2UgZGF0YWZyYW1lIGZvciBlYWNoIGNhcmQgdHlwZQoKI3dlbm4ganVuaW9yX2NhcmQgaXMgdHJ1ZSBwaXBlIGludG8gbmV3IGRhdGEgZnJhbWUKY2xpZW50X2p1bmlvciA8LSBmaWx0ZXIoY2xpZW50X2Rpc3AgLCB0eXBlX2NhcmQgPT0gJ2p1bmlvcicpCmNsaWVudF9jbGFzc2ljIDwtIGZpbHRlcihjbGllbnRfZGlzcCAsIHR5cGVfY2FyZCA9PSAnY2xhc3NpYycpCmNsaWVudF9nb2xkIDwtIGZpbHRlcihjbGllbnRfZGlzcCAsIHR5cGVfY2FyZCA9PSAnZ29sZCcpCgpjbGllbnRfYWxsX2NhcmRzIDwtIGNsaWVudF9kaXNwICU+JQogIGZpbHRlcighaXMubmEodHlwZV9jYXJkKSkKCmNsaWVudF9uYSA8LSBjbGllbnRfZGlzcCAlPiUKICBmaWx0ZXIoaXMubmEodHlwZV9jYXJkKSkKCmNsaWVudF9uYQoKY2xpZW50X25hX2p1bmlvciA8LSBmaWx0ZXIoY2xpZW50X25hLCBhZ2UgPD0gMjMpCmNsaWVudF9uYV9jbGFzc2ljX2dvbGQgPC0gZmlsdGVyKGNsaWVudF9uYSwgYWdlID4gMjMpCmBgYAoKYGBge3J9CiMgY2xpZW50X2p1bmlvciRhZ2VfY2FyZF9pc3N1ZWQyIDwtIGNsaWVudF9qdW5pb3IkY2FyZF9pc3N1ZWQgLSBjbGllbnRfanVuaW9yJGJpcnRoZGF5IApjbGllbnRfanVuaW9yJGFnZV9jYXJkX2lzc3VlZCA8LSBmbG9vcihhZ2VfY2FsYyhhcy5EYXRlKGNsaWVudF9qdW5pb3IkYmlydGhkYXkpLGNsaWVudF9qdW5pb3IkY2FyZF9pc3N1ZWQsIHVuaXRzID0gInllYXJzIikpCgpqdW5pb3JfaXNzdWVkX2FnZV92aXogPC0gZ2dwbG90KCBjbGllbnRfanVuaW9yLCBhZXMoIHggPSBhZ2VfY2FyZF9pc3N1ZWQsIGZpbGwgPSBnZW5kZXIpKSsKICBnZW9tX2JhciggcG9zaXRpb24gPSAnZG9kZ2UnCiAgKSsKICAjIGdlb21fZGVuc2l0eSgpKwogIGdndGl0bGUoJ1xuSnVuaW9yIGNhcmRzIGlzc3VlZCBvbiBhZ2Ugb2Ygb3duZXJcbicpKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkKICAgICkKanVuaW9yX2lzc3VlZF9hZ2Vfdml6CgpjbGllbnRfbmFfanVuaW9yX2FnZV92aXogPC0gZ2dwbG90KGNsaWVudF9uYV9qdW5pb3IsIGFlcyh4PWFnZSwgZmlsbD1nZW5kZXIpKSsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICdkb2RnZScpKwogIGdndGl0bGUoJ1xucG90ZW50aWFsIGp1bmlvciBjYXJkIGNsaWVudHMgYWdlIHNwcmVhZFxuJykrCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KQogICkKY2xpZW50X25hX2p1bmlvcl9hZ2Vfdml6CgpgYGAKCmBgYHtyfQpjbGllbnRfY2xhc3NpYyRhZ2VfY2FyZF9pc3N1ZWQgPC0gZmxvb3IoYWdlX2NhbGMoYXMuRGF0ZShjbGllbnRfY2xhc3NpYyRiaXJ0aGRheSksY2xpZW50X2NsYXNzaWMkY2FyZF9pc3N1ZWQsIHVuaXRzID0gJ3llYXJzJykpCmNsaWVudF9nb2xkJGFnZV9jYXJkX2lzc3VlZCA8LSBmbG9vcihhZ2VfY2FsYyhhcy5EYXRlKGNsaWVudF9nb2xkJGJpcnRoZGF5KSxjbGllbnRfZ29sZCRjYXJkX2lzc3VlZCwgdW5pdHMgPSAneWVhcnMnKSkKCmNsYXNzaWNfaXNzdWVkX2FnZV92aXogPC0gZ2dwbG90KGNsaWVudF9jbGFzc2ljLCBhZXMoIHggPSBhZ2UsIGZpbGwgPSBnZW5kZXIpKSsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICdkb2RnZScpKwogIGdndGl0bGUoJ1xuQ2xhc3NpYyBjYXJkcyBpc3N1ZWQgb24gYWdlIG9mIG93bmVyXG4nKSsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpCiAgICApCmNsYXNzaWNfaXNzdWVkX2FnZV92aXoKCiNuZWhtZW4gd2lyIGFsbGUgYWIgMjAgenUgZGVyIGdydXBwZSBwb3RlbnRpYWwgY2xhc3NpYz8/Pz8/Pz8/Cgpnb2xkX2lzc3VlZF9hZ2Vfdml6IDwtIGdncGxvdChjbGllbnRfZ29sZCwgYWVzKCB4ID0gYWdlLCBmaWxsID0gZ2VuZGVyKSkrCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAnZG9kZ2UnKSsKICBnZ3RpdGxlKCdcbkdvbGQgY2FyZHMgaXNzdWVkIG9uIGFnZSBvZiBvd25lclxuJykrCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KQogICAgKQpnb2xkX2lzc3VlZF9hZ2Vfdml6CgpgYGAKCmBgYHtyfQojam9pbiBjYXJkIGluZm9ybWF0aW9uIHRvIHRyYWFuc2FjdGlvbnMgdmlhIGFjY291bnQgaWQKCmNhcmRvd25lcl90cmFuc2FjdGlvbnMgPC0gaW5uZXJfam9pbihjbGllbnRfYWxsX2NhcmRzLCB0cmFucywgYnkgPSAnYWNjb3VudF9pZCcpICU+JQogIG11dGF0ZSh0cmFuc19jcmVkaXQgPQogICAgY2FzZV93aGVuKAogICAgICB0eXBlID09ICdjcmVkaXQnIH4gMSwKICAgICAgdHlwZSAhPSAnY3JlZGl0JyB+IDAKICAgICkKICApICU+JQogIG11dGF0ZSh0cmFuc193aXRoZHJhd2FsID0KICAgICAgICAgICBjYXNlX3doZW4oCiAgICAgICAgICAgICB0eXBlID09ICd3aXRoZHJhd2FsJyB+IDEsCiAgICAgICAgICAgICB0eXBlICE9ICd3aXRoZHJhd2FsJyB+IDAKICAgICAgICAgICApCiAgKSAlPiUKICBtdXRhdGUoCiAgICB0eXBlID0gYXMuZmFjdG9yKHR5cGUpLAogICAgb3BlcmF0aW9uID0gYXMuZmFjdG9yKG9wZXJhdGlvbiksCiAgICBrX3N5bWJvbCA9IGFzLmZhY3RvcihrX3N5bWJvbCksCiAgICBiYW5rID0gYXMuZmFjdG9yKGJhbmspCiAgKQoKanVuaW9yX2NhcmRfdHJhbnNhY3Rpb25zIDwtIGZpbHRlcihjYXJkb3duZXJfdHJhbnNhY3Rpb25zLCB0eXBlX2NhcmQgPT0gJ2p1bmlvcicpCmNsYXNzaWNfY2FyZF90cmFuc2FjdGlvbnMgPC0gZmlsdGVyKGNhcmRvd25lcl90cmFuc2FjdGlvbnMsIHR5cGVfY2FyZCA9PSAnY2xhc3NpYycpCmdvbGRfY2FyZF90cmFuc2FjdGlvbnMgPC0gZmlsdGVyKGNhcmRvd25lcl90cmFuc2FjdGlvbnMsIHR5cGVfY2FyZCA9PSAnZ29sZCcpCmBgYAoKCmBgYHtyfQpqdW5pb3JfY2FyZF90cmFuc2FjdGlvbnNfMiA8LSBqdW5pb3JfY2FyZF90cmFuc2FjdGlvbnMgJT4lCiAgZ3JvdXBfYnkoYWNjb3VudF9pZCwgdHlwZSkgJT4lCiAgc3VtbWFyaXNlKAogICAgY291bnQgPSBuKCkKICApIApqdW5pb3JfY2FyZF90cmFuc2FjdGlvbnNfMgoKCgpgYGAKCmBgYHtyfQoKI3p1ZXJzdCBkdXJjaHNjaG5pdHQgcHJvIGdlbmRlciBiZXJlY2huZW4gdW5kIGRhbm4gbWVhbiBwcm8gZ2VuZGVyIGFuZ2ViZW4KCmp1bmlvcl90eXBlX3N1bSA8LSBqdW5pb3JfY2FyZF90cmFuc2FjdGlvbnMkdHlwZSAlPiUKICBzdW1tYXJ5KCkKCmNsYXNzaWNfdHlwZV9zdW0gPC0gY2xhc3NpY19jYXJkX3RyYW5zYWN0aW9ucyR0eXBlICU+JQogIHN1bW1hcnkoKQoKZ29sZF90eXBlX3N1bSA8LSBnb2xkX2NhcmRfdHJhbnNhY3Rpb25zJHR5cGUgJT4lCiAgc3VtbWFyeSgpCgpwcmludCgnanVuaW9yX3R5cGUnKQpqdW5pb3JfdHlwZV9zdW0KcHJpbnQoJ2NsYXNzaWNfdHlwZScpCmNsYXNzaWNfdHlwZV9zdW0KcHJpbnQoJ2dvbGRfdHlwZScpCmdvbGRfdHlwZV9zdW0KCgojTmEgdW50ZXJzdWNoZW4ganVuaW9yY2FyZApqdW5pb3JfY2FyZF90cmFuc2FjdGlvbnNfbmEgPC0gZmlsdGVyKGp1bmlvcl9jYXJkX3RyYW5zYWN0aW9ucywgaXMubmEodHlwZSkpIAoKanVuaW9yX2NhcmRfdHJhbnNhY3Rpb25zX25hX3N1bSA8LSBqdW5pb3JfY2FyZF90cmFuc2FjdGlvbnNfbmEkb3BlcmF0aW9uICU+JQogIHN1bW1hcnkoKQpqdW5pb3JfY2FyZF90cmFuc2FjdGlvbnNfbmFfc3VtCgojbmEgdW50ZXJzdWNoZW4gY2xhc3NpYyBjYXJkCmNsYXNzaWNfY2FyZF90cmFuc2FjdGlvbnNfbmEgPC0gZmlsdGVyKGNsYXNzaWNfY2FyZF90cmFuc2FjdGlvbnMsIGlzLm5hKHR5cGUpKSAKCmNsYXNzaWNfY2FyZF90cmFuc2FjdGlvbnNfbmFfc3VtIDwtIGNsYXNzaWNfY2FyZF90cmFuc2FjdGlvbnNfbmEkb3BlcmF0aW9uICU+JQogIHN1bW1hcnkoKQpjbGFzc2ljX2NhcmRfdHJhbnNhY3Rpb25zX25hX3N1bQoKI25hIHVudGVyc3VjaGVuIGdvbGQgY2FyZApnb2xkX2NhcmRfdHJhbnNhY3Rpb25zX25hIDwtIGZpbHRlcihnb2xkX2NhcmRfdHJhbnNhY3Rpb25zLCBpcy5uYSh0eXBlKSkgCmBgYAoKYGBge3J9CmNsaWVudF9nZW5kZXIgPC1nZ3Bsb3QoCiAgY2xpZW50LCBhZXMoeCA9IGdlbmRlciwgZmlsbCA9IGdlbmRlcikpKwogIGdlb21fYmFyKCkrCiAgZ2d0aXRsZSgnXG5DbGllbnRzIHNwcmVhZCBvbiBnZW5kZXJcbicpKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkKICAgICkrCiAgbGFicyggeT0gJ1xuTnVtYmVyIG9mIENsaWVudHNcbicsIHggPSAnXG5HZW5kZXJcbicpCmNsaWVudF9nZW5kZXIKCmBgYAoKVGhlIGdlbmVyYWwgaW5mb3JtYXRpb24gb2YgdGhlIEFnZSBvZiB0aGUgY2xpZW50cyBpcyBhIGdvb2QgYmFzZSBpbmZvcm1hdGlvbiBhcyB3ZWxsLgoKCmBgYHtyfQpjbGllbnRfYWdlIDwtIGdncGxvdCgKICBjbGllbnQsIGFlcyh4ID0gYWdlLGNvbG91ciA9IGdlbmRlcikpKwogICMgZ2VvbV9iYXIoYWxwaGEgPSAwLjUpKwogIGdlb21fZGVuc2l0eSgpKwogIGdndGl0bGUoJ1xuQ2xpZW50c3ByZWFkIG9uIGFnZSwgc2VwYXJhdGVkIGJ5IGdlbmRlclxuJykrCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KQogICAgKSsKICBsYWJzKCB5PSAnXG5kZW5zaXR5XG4nLCB4ID0gJ1xuQWdlXG4nKQogIApjbGllbnRfYWdlCmBgYAoKYGBge3J9CmNhcmRfdHlwZSA8LSBnZ3Bsb3QoCiAgY2FyZCwgYWVzKHggPSB0eXBlLCBmaWxsID0gdHlwZSkpKwogIGdlb21fYmFyKCkrCiAgZ2d0aXRsZSgnXG5TcHJlYWQgb2YgY2FyZCB0eXBlc1xuJykrCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KQogICAgKQogIApjYXJkX3R5cGUKCgpnb2xkX2NhcmRfdHJhbnNhY3Rpb25zX25hX3N1bSA8LSBnb2xkX2NhcmRfdHJhbnNhY3Rpb25zX25hJG9wZXJhdGlvbiAlPiUKICBzdW1tYXJ5KCkKZ29sZF9jYXJkX3RyYW5zYWN0aW9uc19uYV9zdW0KCmBgYAoKCmBgYHtyfQoKanVuaW9yX3RyYW5zX3ZpeiA8LSBnZ3Bsb3QoanVuaW9yX2NhcmRfdHJhbnNhY3Rpb25zLCBhZXMoIHggPSB0eXBlLCBmaWxsID0gZ2VuZGVyKSkrCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAnZG9kZ2UnKSsKICBnZ3RpdGxlKCdcbkNyZWRpdCBjb21wYXJlZCB0byB3aXRoZHJhd2FscyBKdW5pb3IgQ2FyZFxuJykrCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KQogICkKanVuaW9yX3RyYW5zX3ZpegoKCgoKY2xhc3NpY190cmFuc192aXogPC0gZ2dwbG90KGNsYXNzaWNfY2FyZF90cmFuc2FjdGlvbnMsIGFlcyggeCA9IHR5cGUsIGZpbGwgPSBnZW5kZXIpKSsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICdkb2RnZScpKwogIGdndGl0bGUoJ1xuQ3JlZGl0IGNvbXBhcmVkIHRvIHdpdGhkcmF3YWxzIGNsYXNzaWMgY2FyZFxuJykrCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KQogICkKY2xhc3NpY190cmFuc192aXoKCmdvbGRfdHJhbnNfdml6IDwtIGdncGxvdChnb2xkX2NhcmRfdHJhbnNhY3Rpb25zLCBhZXMoIHggPSB0eXBlLCBmaWxsID0gZ2VuZGVyKSkrCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAnZG9kZ2UnKSsKICBnZ3RpdGxlKCdcbkNyZWRpdCBjb21wYXJlZCB0byB3aXRoZHJhd2FscyBnb2xkIGNhcmRcbicpKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkKICApCmdvbGRfdHJhbnNfdml6CmBgYAoKYGBge3J9CmRmX2NsaWVudF9kaXNwID0gY2xpZW50ICU+JSBmdWxsX2pvaW4oZGlzcCwgYnkgPSJjbGllbnRfaWQiKSAlPiUKICBzZWxlY3QoLWRpc3RyaWN0X2lkLCAtYmlydGhfbnVtYmVyLCAtYmlydGhkYXkpCmRmX2FjY291bnRfY2xpZW50X2Rpc3AgPSBhY2NvdW50ICU+JSBmdWxsX2pvaW4oZGZfY2xpZW50X2Rpc3AsIGJ5ID0gImFjY291bnRfaWQiKQoKc3RyKGRmX2FjY291bnRfY2xpZW50X2Rpc3ApCnN1bW1hcnkoZGZfYWNjb3VudF9jbGllbnRfZGlzcCkKbnJvdyhkZl9hY2NvdW50X2NsaWVudF9kaXNwKQpgYGAKCmBgYHtyfQojZGVuc2l0eSBwbG90LCB3b21lbiBhbmQgbWVuIHNlcGFyYXRlZApkZl9hY2NvdW50X2NsaWVudF9kaXNwICU+JSBnZ3Bsb3QoYWVzKHggPSBhZ2UsIGNvbG9yID0gZ2VuZGVyKSkgKwogICAgZ2VvbV9kZW5zaXR5KHNpemUgPSAxKSArIHhsYWIoJ0FnZSBvZiBjbGllbnRzJykKYGBgCgpgYGB7cn0KI3R1cm5pbmcgcG9pbnRzIGluIGFnZQojaW4gZ2VuZXJhbApucjEgPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcCAlPiUKICBmaWx0ZXIoYWdlID09IDE2KSAlPiUKICBucm93KCkKbnIxCgpucjIgPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcCAlPiUKICBmaWx0ZXIoYWdlID09IDE3KSAlPiUKICBucm93KCkKbnIyCgpucjMgPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcCAlPiUKICBmaWx0ZXIoYWdlID09IDU4KSAlPiUKICBucm93KCkKbnIzCgpucjQgPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcCAlPiUKICBmaWx0ZXIoYWdlID09IDU5KSAlPiUKICBucm93KCkKbnI0CgpucjUgPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcCAlPiUKICBmaWx0ZXIoYWdlID09IDc5KSAlPiUKICBucm93KCkKbnI1CgpucjYgPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcCAlPiUKICBmaWx0ZXIoYWdlID09IDgwKSAlPiUKICBucm93KCkKbnI2CgojdHVybmluZyBwb2ludHMgaW4gYWdlCiNmb3Igd29tZW4KZGZfYWNjb3VudF9jbGllbnRfZGlzcF93IDwtIGRmX2FjY291bnRfY2xpZW50X2Rpc3AgJT4lCiAgZmlsdGVyKGdlbmRlciA9PSAnZicpCgpucncxIDwtIGRmX2FjY291bnRfY2xpZW50X2Rpc3BfdyAlPiUKICBmaWx0ZXIoYWdlID09IDE2KSAlPiUKICBucm93KCkKbnJ3MQoKbnJ3MiA8LSBkZl9hY2NvdW50X2NsaWVudF9kaXNwX3cgJT4lCiAgZmlsdGVyKGFnZSA9PSAxNykgJT4lCiAgbnJvdygpCm5ydzIKCm5ydzMgPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcF93ICU+JQogIGZpbHRlcihhZ2UgPT0gNTgpICU+JQogIG5yb3coKQpucnczCgpucnc0IDwtIGRmX2FjY291bnRfY2xpZW50X2Rpc3BfdyAlPiUKICBmaWx0ZXIoYWdlID09IDU5KSAlPiUKICBucm93KCkKbnJ3NAoKbnJ3NSA8LSBkZl9hY2NvdW50X2NsaWVudF9kaXNwX3cgJT4lCiAgZmlsdGVyKGFnZSA9PSA3OSkgJT4lCiAgbnJvdygpCm5ydzUKCm5ydzYgPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcF93ICU+JQogIGZpbHRlcihhZ2UgPT0gODApICU+JQogIG5yb3coKQpucnc2CgojZm9yIG1lbgpkZl9hY2NvdW50X2NsaWVudF9kaXNwX20gPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcCAlPiUKICBmaWx0ZXIoZ2VuZGVyID09ICdtJykKCm5ybTEgPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcF9tICU+JQogIGZpbHRlcihhZ2UgPT0gMTYpICU+JQogIG5yb3coKQpucm0xCgpucm0yIDwtIGRmX2FjY291bnRfY2xpZW50X2Rpc3BfbSAlPiUKICBmaWx0ZXIoYWdlID09IDE3KSAlPiUKICBucm93KCkKbnJtMgoKbnJtMyA8LSBkZl9hY2NvdW50X2NsaWVudF9kaXNwX20gJT4lCiAgZmlsdGVyKGFnZSA9PSA2MikgJT4lCiAgbnJvdygpCm5ybTMKCm5ybTQgPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcF9tICU+JQogIGZpbHRlcihhZ2UgPT0gNjMpICU+JQogIG5yb3coKQpucm00Cgpucm01IDwtIGRmX2FjY291bnRfY2xpZW50X2Rpc3BfbSAlPiUKICBmaWx0ZXIoYWdlID09IDc5KSAlPiUKICBucm93KCkKbnJtNQoKbnJtNiA8LSBkZl9hY2NvdW50X2NsaWVudF9kaXNwX20gJT4lCiAgZmlsdGVyKGFnZSA9PSA4MCkgJT4lCiAgbnJvdygpCm5ybTYKYGBgCgoKYGBge3J9CiNiYXIgY2hhcnQsIG9uZSBiYXIgZm9yIGVhY2ggYWdlCmRmX2FjY291bnRfY2xpZW50X2Rpc3AgJT4lIGdncGxvdChhZXMoeCA9IGFnZSkpICsgZ2VvbV9iYXIoKSArIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgCgojYmFyIGNoYXJ0LCB3b21lbiBhbmQgbWVuIHNlcGFyYXRlZCwgb25lIGJhciBmb3IgZWFjaCBhZ2UKZGZfYWNjb3VudF9jbGllbnRfZGlzcCAlPiUgZ2dwbG90KGFlcyh4ID0gYWdlLCBmaWxsID0gZ2VuZGVyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICdkb2RnZScpICsKICAgICAgICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArIHhsYWIoJ0FnZSBvZiBjbGllbnRzJykKCiNzdGFja2VkIGJhciBjaGFydCwgd29tZW4gYW5kIG1lbiBzZXBhcmF0ZWQsIG9uZSBiYXIgZm9yIGVhY2ggYWdlCmRmX2FjY291bnRfY2xpZW50X2Rpc3AgJT4lIGdncGxvdChhZXMoeCA9IGFnZSwgZmlsbCA9IGdlbmRlcikpICsgZ2VvbV9iYXIoKSArCiAgICAgICAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKyB4bGFiKCdBZ2Ugb2YgY2xpZW50cycpCgojdHdvIGJhciBjaGFydHMsIHdvbWVuIGFuZCBtZW4gc2VwYXJhdGVkLCBlYWNoIGFnZSBvbmUgYmFyCmRmX2FjY291bnRfY2xpZW50X2Rpc3AgJT4lIGdncGxvdChhZXMoeCA9IGFnZSwgZmlsbCA9IGdlbmRlcikpICsgZ2VvbV9iYXIoKSArCiAgICAgICAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKyBmYWNldF93cmFwKH4gZ2VuZGVyKSArIHhsYWIoJ0FnZSBvZiBjbGllbnRzJykKCiNjb29yZGluYXRpb24gZmxpcHBlZCBiYXIgY2hhcnQsIG9tZW4gYW5kIG1lbiBzZXBhcmF0ZWQsIG9uZSBiYXIgZm9yIGVhY2ggYWdlCmRmX2FjY291bnRfY2xpZW50X2Rpc3AgJT4lIGdncGxvdChhZXMoeCA9IGFnZSwgZmlsbCA9IGdlbmRlcikpICsgZ2VvbV9iYXIoKSArIGNvb3JkX2ZsaXAoKSArCiAgICAgICAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKyB4bGFiKCdBZ2Ugb2YgY2xpZW50cycpCgojY29vcmRpbmF0aW9uIGZsaXBwZWQgYmFyIGNoYXJ0LCBvbWVuIGFuZCBtZW4gc2VwYXJhdGVkLCBvbmUgYmFyIGZvciBlYWNoIGFnZSwgaW4gcGVyY2VudGFnZQpkZl9hY2NvdW50X2NsaWVudF9kaXNwICU+JSBnZ3Bsb3QoYWVzKHggPSBhZ2UsIGZpbGwgPSBnZW5kZXIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gJ2ZpbGwnKSArCiAgY29vcmRfZmxpcCgpICsgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArIHhsYWIoJ0FnZSBvZiBjbGllbnRzJykKCmBgYAoKYGBge3J9CiNvcmRlciB0aGUgY2xpZW50cyBieSB5b3VuZ2VzdCBhbmQgb2xkZXN0LCB5b3VuZ2VzdCBpcyAxMCwgb2xkZXN0IGlzIDg2CiNncm91cCBhbGwgdGhlIGNsaWVudHMgaW4gNyBkaWZmZXJlbnQgZ3JvdXBzCmRmX2FjY291bnRfY2xpZW50X2Rpc3AgPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcCAlPiUKICBtdXRhdGUoYWdlX2dyb3VwZWQgPSBjYXNlX3doZW4oCiAgICBhZ2UgPD0gMTYgfiAnMS0xNicsCiAgICBhZ2UgPD0gMzIgfiAnMTctMzInLAogICAgYWdlIDw9IDQ4IH4gJzMzLTQ4JywKICAgIGFnZSA8PSA2NCB+ICc0OS02NCcsCiAgICBhZ2UgPD0gNzIgfiAnNjUtNzInLAogICAgYWdlIDw9IDg2IH4gJzczLTg2JywKICAgIFRSVUUgfiAnbm90IGtub3duJwogICkpCgojZmFjdG9yIHRoZSBncm91cHMKZGZfYWNjb3VudF9jbGllbnRfZGlzcCA8LSBkZl9hY2NvdW50X2NsaWVudF9kaXNwICU+JSAKICBtdXRhdGUoYWdlX2dyb3VwZWQgPSBhc19mYWN0b3IoYWdlX2dyb3VwZWQpKQoKI29yZGVyIHRoZSBuZXcgYWdlIGNvbHVtbiBpbiBhIGRldGVybWluZWQgd2F5CmRmX2FjY291bnRfY2xpZW50X2Rpc3AkYWdlMyA8LSAKICBvcmRlcmVkKGRmX2FjY291bnRfY2xpZW50X2Rpc3AkYWdlX2dyb3VwZWQsIGxldmVscyA9IGMoJzEtMTYnLCAnMTctMzInLCAnMzMtNDgnLCAnNDktNjQnLCAnNjUtNzInLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnNzMtODYnKSkKYGBgCgoKYGBge3J9CiNiYXIgY2hhcnQsIGFsbCBjbGllbnRzIGluIDcgZ3JvdXBzCmRmX2FjY291bnRfY2xpZW50X2Rpc3AgJT4lIGdncGxvdChhZXMoeCA9IGZhY3RvcihhZ2VfZ3JvdXBlZCkpKSArIGdlb21fYmFyKCkgKwogICAgICAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlBhaXJlZCIpICsgeGxhYignQWdlIG9mIGNsaWVudHMnKQoKI3R3byBiYXIgY2hhcnRzLCB3b21lbiBhbmQgbWVuIHNlcGFyYXRlZCwgNyBncm91cHMgCmRmX2FjY291bnRfY2xpZW50X2Rpc3AgJT4lIGdncGxvdChhZXMoeCA9IGFnZV9ncm91cGVkLCBmaWxsID0gZ2VuZGVyKSkgKyBnZW9tX2JhcigpICsKICAgICAgICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArIGZhY2V0X3dyYXAofiBnZW5kZXIpKyB4bGFiKCdBZ2Ugb2YgY2xpZW50cycpCgojYmFyIGNoYXJ0LCB3b21lbiBhbmQgbWVuIHNlcGFyYXRlZCwgNyBncm91cHMgCmRmX2FjY291bnRfY2xpZW50X2Rpc3AgJT4lIGdncGxvdChhZXMoeCA9IGFnZV9ncm91cGVkLCBmaWxsID0gZ2VuZGVyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICdkb2RnZScpICsKICAgICAgICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArIHhsYWIoJ0FnZSBvZiBjbGllbnRzJykKCiNzdGFja2VkIGJhciBjaGFydCwgd29tZW4gYW5kIG1lbiBzZXBhcmF0ZWQsIDcgZ3JvdXBzIApkZl9hY2NvdW50X2NsaWVudF9kaXNwICU+JSBnZ3Bsb3QoYWVzKHggPSBhZ2VfZ3JvdXBlZCwgZmlsbCA9IGdlbmRlcikpICsgCiAgZ2VvbV9iYXIoKSArIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKyB4bGFiKCdBZ2Ugb2YgY2xpZW50cycpCgojcmVvcmRlciB0aGUgYWdlMyBjb2x1bW4gdG8gYXNjZW5kaW5nCmRmX2FjY291bnRfY2xpZW50X2Rpc3AgPC0gZGZfYWNjb3VudF9jbGllbnRfZGlzcCAlPiUKICBtdXRhdGUoYWdlMyA9IGZjdF9yZW9yZGVyKGFnZV9ncm91cGVkLCBkZXNjKGFnZV9ncm91cGVkKSkpIAoKI2Nvb3JkaW5hdGlvbiBmbGlwcGVkIGJhciBjaGFydCwgd29tZW4gYW5kIG1lbiBzZXBhcmF0ZWQsIDcgZ3JvdXBzIApkZl9hY2NvdW50X2NsaWVudF9kaXNwICU+JSBnZ3Bsb3QoYWVzKHggPSBhZ2VfZ3JvdXBlZCwgZmlsbCA9IGdlbmRlcikpICsgCiAgZ2VvbV9iYXIoKSArIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKwogIGNvb3JkX2ZsaXAoKSArIHhsYWIoJ0FnZSBvZiBjbGllbnRzJykKCiNjb29yZGluYXRpb24gZmxpcHBlZCBiYXIgY2hhcnQsIHdvbWVuIGFuZCBtZW4gc2VwYXJhdGVkLCA3IGdyb3VwcywgaW4gcGVyY2VudGFnZQpkZl9hY2NvdW50X2NsaWVudF9kaXNwICU+JSBnZ3Bsb3QoYWVzKHggPSBhZ2VfZ3JvdXBlZCwgZmlsbCA9IGdlbmRlcikpICsgCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAnZmlsbCcpICsgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArIGNvb3JkX2ZsaXAoKSArIAogIHhsYWIoJ0FnZSBvZiBjbGllbnRzJykgKyB5bGFiKCdEZW5zaXR5JykgCmBgYAoKCgoKCgoKCgoKCgoK